package com.easipass.unifiedconfig;

import java.io.Serializable;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 
 * @version $Id$
 * @author itea
 * @date 2010-1-28
 */
public final class Parameter implements Serializable, Cloneable {

	public enum AccessLevel {
		PUBLIC,
		PRIVATE
	}
	
	private static final long serialVersionUID = 3632341180025215795L;
	
	private UCI uci;
	private Set<String> values = new LinkedHashSet<String>();
	private AccessLevel accessLevel = AccessLevel.PUBLIC;
	
	public Parameter() {}
	
	public Parameter(UCI uci){
		this.uci = uci;
	}
	
	public Parameter(String uci) throws MalformedUCIException {
		this.uci = new UCI(uci);
	}
	
	/** Clone */
	public Parameter(Parameter p){
		this.uci = p.uci;
		this.values.addAll(p.values);
		this.accessLevel = p.accessLevel;
	}
	
	/** Copy */
	public Parameter(UCI newUci, Parameter p){
		this.uci = newUci;
		this.values.addAll(p.values);
		this.accessLevel = p.accessLevel;
	}
	
	public Parameter(UCI uci, AccessLevel accessLevel, String... values){
		this.uci = uci;
		this.setValues(values);
		this.setAccessLevel(accessLevel);
	}

	public Parameter(UCI uci, String... values){
		this(uci, AccessLevel.PUBLIC, values);
	}
	
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(uci).append(" = ").append(accessLevel)
		.append(" {");
		String[] values = this.values.toArray(new String[0]);
		for(int i = 0; i<values.length; i++) {
			builder.append(values[i]);
			if(i != values.length -1) builder.append(", ");
		}
		builder.append("}");
		return builder.toString();
	}

	@Override
	public Parameter clone() {
		return new Parameter(this);
	}
	
	public int size() {
		return values.size();
	}
	public UCI getUci() {
		return uci;
	}
	public void setUci(UCI uci) {
		this.uci = uci;
	}
	public String getName() {
		return uci == null ? null : uci.getParameterName();
	}
	public String[] getValues() {
		return values.toArray(new String[0]);
	}
	public synchronized void setValues(String... values) {
		this.values.clear();
		if(values == null) values = new String[0];
		for(String s : values)
			if((s = trimNull(s)) != null)
				this.values.add(s);
	}
	public synchronized void setValue(String value) {
		this.setValues(new String[]{value});
	}
	public String getValue() {
		return values.isEmpty() ? null : values.iterator().next();
	}
	public synchronized void insertValues(String... vals) {
		for(String s : vals)
			if((s = trimNull(s)) != null)
				values.add(s);
	}
	public synchronized void deleteValues(String... vals) {
		for(String s : vals)
			if((s = trimNull(s)) != null)
				values.remove(s);
	}
	public boolean containsValue(String v) {
		return values.contains(v);
	}
	public AccessLevel getAccessLevel() {
		return accessLevel;
	}
	public void setAccessLevel(AccessLevel accessLevel) {
		this.accessLevel = accessLevel;
	}
	
	private static String trimNull(String s) {
		if(s == null) return null;
		return (s = s.trim()).length() == 0 ? null : s;
	}
}
